package server

import (
	"database/sql"
	"encoding/json"
	"errors"
)

//获取家族列表
func get_family_list(tx *sql.Tx, person_id int64, jsonData string) *ReturnStruct {
	data, err := api_get_family_list(tx, person_id)
	if err != nil {
		return FailRet(CodeDatabaseError, err)
	}
	return SuccRet(data)
}

//选择家族，获取新家族信息
func select_family(tx *sql.Tx, person_id int64, jsonData string) *ReturnStruct {
	type FamilyInput struct {
		FamilyId int64 `json:"family_id"`
	}
	var input FamilyInput
	err := json.Unmarshal([]byte(jsonData), &input)
	if err != nil {
		return FailRet(CodeParamError, err)
	}
	family_id := input.FamilyId
	if family_id == 0 {
		return FailRet(CodeParamError, "param is error!")
	}

	var count int64
	err = tx.QueryRow(`select count(*) from 
		tb_family a 
		where a.id = ? 
			and exists(select * from tb_family_member where family_id = ? and person_id = ?)`,
		family_id, family_id, person_id).Scan(&count)
	if err != nil {
		return FailRet(CodeDatabaseError, err)
	}
	if count == 0 {
		return FailRet(CodeSvrERROR, errors.New("家族已不包含此人"))
	}

	_, err = tx.Exec("update tb_person set default_family = ? where id = ?", family_id, person_id)
	if err != nil {
		return DBErrReturn("切换家族-更新默认家族失败", err)
	}

	result, err := api_get_family_info(tx, person_id, family_id)
	if err != nil {
		return FailRet(CodeDatabaseError, err)
	}
	return SuccRet(result)
}

//获取一个家族中的所有成员
func get_family_members(tx *sql.Tx, person_id int64, jsonData string) *ReturnStruct {
	type InputInfo struct {
		Family int64 `json:"family"`
	}
	var input InputInfo
	err := json.Unmarshal([]byte(jsonData), &input)
	if err != nil {
		return FailRet(CodeParamError, err)
	}

	//校验当前人
	isContains, err := api_family_contain_person(tx, input.Family, []int64{person_id})
	if err != nil {
		return DBErrReturn("校验当前人异常", err)
	}
	if !isContains {
		return ParamErrReturn("校验当前人失败")
	}

	//查询
	result, err := api_get_family_members(tx, person_id, input.Family)
	if err != nil {
		return FailRet(CodeDatabaseError, err)
	}
	return SuccRet(result)
}

//添加家族人员：

//添加父亲
func family_add_father(tx *sql.Tx, person_id int64, jsonData string) *ReturnStruct {
	type InputInfo struct {
		Family       int64 `json:"family"`
		TargetPerson int64 `json:"target_person"` //要添加父亲的人

		SelectPerson int64 `json:"select_person"` //新增已有人员，如果该字段为0， 就创建人员
		// 人员信息信息
		Name     string `json:"name"`
		Nick     string `json:"nick"`
		Birthday string `json:"birthday"`
		Phone    string `json:"phone"`
		Priority int    `json:"priority"`
	}
	var input InputInfo
	err := json.Unmarshal([]byte(jsonData), &input)
	if err != nil {
		return FailRet(CodeParamError, err)
	}
	target_person := input.TargetPerson
	if input.Priority < 1 || input.Priority > 20 {
		return ParamErrReturn("排行参数超出范围!")
	}

	//校验当前人
	isContains, err := api_family_contain_person(tx, input.Family, []int64{person_id, target_person})
	if err != nil {
		return DBErrReturn("校验当前人异常", err)
	}
	if !isContains {
		return ParamErrReturn("校验当前人失败")
	}

	// 校验是否可以添加
	var id int64
	var child int64
	var child_male int
	var parent int64
	var wife int64
	var husband int64
	var mother int64
	var father int64
	err = tx.QueryRow(`
			select a.id, a.child, child_male, parent, ifnull(b.wife, 0), ifnull(b.husband, 0), ifnull(c.wife, 0) as mother, ifnull(c.husband, 0) as father 
			from tb_parents a 
			join tb_couple b on a.child = b.id 
			left join tb_couple c on a.parent = c.id 
			where a.family = ? and (b.wife = ? or b.husband = ?) `, input.Family, input.TargetPerson, input.TargetPerson).
		Scan(&id, &child, &child_male, &parent, &wife, &husband, &mother, &father)

	if err != nil && err.Error() != sql.ErrNoRows.Error() {
		return DBErrReturn("校验权限", err)
	}
	if id != 0 {
		if parent != 0 {
			if child_male == 1 {
				if wife == target_person {
					return SvrErrReturn("丈夫已经有长辈了，妻子不能有了")
				} else {
					if father != 0 {
						return SvrErrReturn("已经有父亲了，不能再添加")
					}
				}
			} else {
				if husband == target_person {
					return SvrErrReturn("妻子已经有长辈了，丈夫不能有了")
				} else {
					if father != 0 {
						return SvrErrReturn("已经有父亲了，不能再添加")
					}
				}
			}
		} else {
			//没有长辈，可以添加
		}
	} else {
		//没有长辈记录，可以添加
	}

	//校验排行
	if parent > 0 {
		priorities, err := api_get_can_select_priorities(tx, parent)
		if err != nil {
			return FailRet(CodeDatabaseError, err)
		}
		if !ArrContainInt(priorities, input.Priority) {
			return ParamErrReturn("排行参数无效")
		}
	}

	//添加人员
	var newPersonId int64
	if input.SelectPerson == 0 {
		//添加新人员
		result, err := tx.Exec("insert into tb_person(name, sex, birthday, phone) values (?, 1, ?, ?)", input.Name, input.Birthday, input.Phone)
		if err != nil {
			return DBErrReturn("新增人员失败", err)
		}
		newPersonId, err = result.LastInsertId()
		if err != nil {
			return DBErrReturn("新增人员返回错误", err)
		}
		//添加人员昵称
		if len(input.Nick) > 0 {
			_, err = tx.Exec("insert into tb_nicks(family, main_person, call_person, nick) values (?, ?, ?, ?)", input.Family, person_id, newPersonId, input.Nick)
			if err != nil {
				return DBErrReturn("保存人员昵称失败", err)
			}
		}
	} else {
		//添加别的家族的已有人员

		//校验性别
		var id int64
		var sex int
		err = tx.QueryRow("select id, sex from tb_person where id = ?", input.SelectPerson).Scan(&id, &sex)
		if err != nil || id == 0 {
			return DBErrReturn("校验选取人失败", err)
		}
		if sex != 1 {
			return SvrErrReturn("选取人性别错误！")
		}
		//校验选取人不在当前家族
		isContains, err := api_family_contain_person(tx, input.Family, []int64{input.SelectPerson})
		if err != nil {
			return DBErrReturn("校验选取人是否在当前家族异常", err)
		}
		if isContains {
			return SvrErrReturn("选取人在当前家族已经存在，不能添加")
		}
		//校验当前登录用户和选取人同属于某一个家族
		in_one_family, err := api_two_person_in_one_family(tx, person_id, input.SelectPerson)
		if err != nil {
			return FailRet(CodeDatabaseError, err)
		}
		if !in_one_family {
			return SvrErrReturn("选取人错误，选取人和当前登录人不共同属于任一家族")
		}

		//更新人员信息
		_, err = tx.Exec("update tb_person set name = ?, birthday = ?, phone = ? where id = ?", input.Name, input.Birthday, input.Phone, input.SelectPerson)
		if err != nil {
			return DBErrReturn("更新人员信息失败", err)
		}
		//添加人员昵称
		if len(input.Nick) > 0 {
			_, err = tx.Exec("insert into tb_nicks(family, main_person, call_person, nick) values (?, ?, ?, ?)", input.Family, person_id, input.SelectPerson, input.Nick)
			if err != nil {
				return DBErrReturn("更新人员昵称失败", err)
			}
		}

		newPersonId = input.SelectPerson
	}

	//更新家族成员表
	_, err = tx.Exec("insert into tb_family_member(family_id, person_id, add_person_id) values (?, ?, ?)", input.Family, newPersonId, person_id)
	if err != nil {
		return DBErrReturn("新增家族成员失败", err)
	}

	//更新父couple对象
	if 0 == parent {
		result, err := tx.Exec("insert into tb_couple(family, husband, priority) values (?, ?, ?)", input.Family, newPersonId, input.Priority)
		if err != nil {
			return DBErrReturn("插入couple对象", err)
		}
		newCoupleId, err := result.LastInsertId()
		if err != nil {
			return DBErrReturn("新增couple失败", err)
		}
		parent = newCoupleId

	} else {
		_, err := tx.Exec("update tb_couple set husband = ?, priority = ? where id = ?", newPersonId, input.Priority, parent)
		if err != nil {
			return DBErrReturn("更新couple对象", err)
		}
	}

	//更新父子表
	if husband == target_person {
		child_male = 1
	} else {
		child_male = 0
	}
	if id != 0 {
		_, err = tx.Exec("update tb_parents set child_male = ?, parent = ? where id = ?", child_male, parent, id)
		if err != nil {
			return DBErrReturn("更新父子表失败", err)
		}

	} else {
		if child == 0 {
			//寻找要添加父亲的人的couple
			err = tx.QueryRow("select id from tb_couple where family = ? and (wife = ? or husband = ?)", input.Family, target_person, target_person).Scan(&child)
			if err != nil {
				return DBErrReturn("查找当前人的couple失败", err)
			}
			if 0 == child {
				return SvrErrReturn("查找当前人的couple失败")
			}
		}

		result, err := tx.Exec("insert into tb_parents(family, child, child_male, parent) values (?, ?, ?, ?)", input.Family, child, child_male, parent)
		if err != nil {
			return DBErrReturn("新增父子表失败", err)
		}
		num, _ := result.RowsAffected()
		if num == 0 {
			return SvrErrReturn("新增父子表失败")
		}
	}

	ret, err := api_get_family_info(tx, person_id, input.Family)
	if err != nil {
		return FailRet(CodeDatabaseError, err)
	}
	return SuccRet(ret)
}

//添加母亲
func family_add_mother(tx *sql.Tx, person_id int64, jsonData string) *ReturnStruct {
	type InputInfo struct {
		Family       int64 `json:"family"`
		TargetPerson int64 `json:"target_person"` //要添加母亲的人

		SelectPerson int64 `json:"select_person"` //新增已有人员，如果该字段为0， 就创建人员
		// 人员信息信息
		Name     string `json:"name"`
		Nick     string `json:"nick"`
		Birthday string `json:"birthday"`
		Phone    string `json:"phone"`
		Priority int    `json:"priority"`
	}
	var input InputInfo
	err := json.Unmarshal([]byte(jsonData), &input)
	if err != nil {
		return FailRet(CodeParamError, err)
	}
	target_person := input.TargetPerson
	if input.Priority < 1 || input.Priority > 20 {
		return ParamErrReturn("排行参数超出范围!")
	}

	//校验当前人
	isContains, err := api_family_contain_person(tx, input.Family, []int64{person_id, target_person})
	if err != nil {
		return DBErrReturn("校验当前人异常", err)
	}
	if !isContains {
		return ParamErrReturn("校验当前人失败")
	}

	// 校验是否可以添加
	var id int64
	var child int64
	var child_male int
	var parent int64
	var wife int64
	var husband int64
	var mother int64
	var father int64
	err = tx.QueryRow(`
			select a.id, a.child, child_male, parent, ifnull(b.wife, 0), ifnull(b.husband, 0), ifnull(c.wife, 0) as mother, ifnull(c.husband, 0) as father 
			from tb_parents a 
			join tb_couple b on a.child = b.id 
			left join tb_couple c on a.parent = c.id 
			where a.family = ? and (b.wife = ? or b.husband = ?) `, input.Family, input.TargetPerson, input.TargetPerson).
		Scan(&id, &child, &child_male, &parent, &wife, &husband, &mother, &father)

	if err != nil && err.Error() != sql.ErrNoRows.Error() {
		return DBErrReturn("校验权限", err)
	}
	if id != 0 {
		if parent != 0 {
			if child_male == 1 {
				if wife == target_person {
					return SvrErrReturn("丈夫已经有长辈了，妻子不能有了")
				} else {
					if mother != 0 {
						return SvrErrReturn("已经有母亲了，不能再添加")
					}
				}
			} else {
				if husband == target_person {
					return SvrErrReturn("妻子已经有长辈了，丈夫不能有了")
				} else {
					if mother != 0 {
						return SvrErrReturn("已经有母亲了，不能再添加")
					}
				}
			}
		} else {
			//没有长辈，可以添加
		}
	} else {
		//没有长辈记录，可以添加
	}

	//校验排行
	if parent > 0 {
		priorities, err := api_get_can_select_priorities(tx, parent)
		if err != nil {
			return FailRet(CodeDatabaseError, err)
		}
		if !ArrContainInt(priorities, input.Priority) {
			return ParamErrReturn("排行参数无效")
		}
	}

	//添加人员
	var newPersonId int64
	if input.SelectPerson == 0 {
		//添加新人员
		result, err := tx.Exec("insert into tb_person(name, sex, birthday, phone) values (?, 0, ?, ?)", input.Name, input.Birthday, input.Phone)
		if err != nil {
			return DBErrReturn("新增人员失败", err)
		}
		newPersonId, err = result.LastInsertId()
		if err != nil {
			return DBErrReturn("新增人员返回错误", err)
		}
		//添加人员昵称
		if len(input.Nick) > 0 {
			_, err = tx.Exec("insert into tb_nicks(family, main_person, call_person, nick) values (?, ?, ?, ?)", input.Family, person_id, newPersonId, input.Nick)
			if err != nil {
				return DBErrReturn("保存人员昵称失败", err)
			}
		}
	} else {
		//添加别的家族的已有人员

		//校验性别
		var id int64
		var sex int
		err = tx.QueryRow("select id, sex from tb_person where id = ?", input.SelectPerson).Scan(&id, &sex)
		if err != nil || id == 0 {
			return DBErrReturn("校验选取人失败", err)
		}
		if sex != 0 {
			return SvrErrReturn("选取人性别错误！")
		}
		//校验选取人不在当前家族
		isContains, err := api_family_contain_person(tx, input.Family, []int64{input.SelectPerson})
		if err != nil {
			return DBErrReturn("校验选取人是否在当前家族异常", err)
		}
		if isContains {
			return SvrErrReturn("选取人在当前家族已经存在，不能添加")
		}
		//校验当前登录用户和选取人同属于某一个家族
		in_one_family, err := api_two_person_in_one_family(tx, person_id, input.SelectPerson)
		if err != nil {
			return FailRet(CodeDatabaseError, err)
		}
		if !in_one_family {
			return SvrErrReturn("选取人错误，选取人和当前登录人不共同属于任一家族")
		}

		//更新人员信息
		_, err = tx.Exec("update tb_person set name = ?, birthday = ?, phone = ? where id = ?", input.Name, input.Birthday, input.Phone, input.SelectPerson)
		if err != nil {
			return DBErrReturn("更新人员信息失败", err)
		}
		//添加人员昵称
		if len(input.Nick) > 0 {
			_, err = tx.Exec("insert into tb_nicks(family, main_person, call_person, nick) values (?, ?, ?, ?)", input.Family, person_id, input.SelectPerson, input.Nick)
			if err != nil {
				return DBErrReturn("更新人员昵称失败", err)
			}
		}

		newPersonId = input.SelectPerson
	}

	//更新家族成员表
	_, err = tx.Exec("insert into tb_family_member(family_id, person_id, add_person_id) values (?, ?, ?)", input.Family, newPersonId, person_id)
	if err != nil {
		return DBErrReturn("新增家族成员失败", err)
	}

	//更新父couple对象
	if 0 == parent {
		result, err := tx.Exec("insert into tb_couple(family, wife, priority) values (?, ?, ?)", input.Family, newPersonId, input.Priority)
		if err != nil {
			return DBErrReturn("插入couple对象", err)
		}
		newCoupleId, err := result.LastInsertId()
		if err != nil {
			return DBErrReturn("新增couple失败", err)
		}
		parent = newCoupleId

	} else {
		_, err := tx.Exec("update tb_couple set wife = ?, priority = ? where id = ?", newPersonId, input.Priority, parent)
		if err != nil {
			return DBErrReturn("更新couple对象", err)
		}
	}

	//更新父子表
	if husband == target_person {
		child_male = 1
	} else {
		child_male = 0
	}
	if id != 0 {
		_, err = tx.Exec("update tb_parents set child_male = ?, parent = ? where id = ?", child_male, parent, id)
		if err != nil {
			return DBErrReturn("更新父子表失败", err)
		}

	} else {
		if child == 0 {
			//寻找要添加父亲的人的couple
			err = tx.QueryRow("select id from tb_couple where family = ? and (wife = ? or husband = ?)", input.Family, target_person, target_person).Scan(&child)
			if err != nil {
				return DBErrReturn("查找当前人的couple失败", err)
			}
			if 0 == child {
				return SvrErrReturn("查找当前人的couple失败")
			}
		}

		result, err := tx.Exec("insert into tb_parents(family, child, child_male, parent) values (?, ?, ?, ?)", input.Family, child, child_male, parent)
		if err != nil {
			return DBErrReturn("新增父子表失败", err)
		}
		num, _ := result.RowsAffected()
		if num == 0 {
			return SvrErrReturn("新增父子表失败")
		}
	}

	ret, err := api_get_family_info(tx, person_id, input.Family)
	if err != nil {
		return FailRet(CodeDatabaseError, err)
	}
	return SuccRet(ret)
}

//添加丈夫
func family_add_husband(tx *sql.Tx, person_id int64, jsonData string) *ReturnStruct {
	type InputInfo struct {
		Family       int64 `json:"family"`
		TargetPerson int64 `json:"target_person"` //要添加丈夫的人

		SelectPerson int64 `json:"select_person"` //新增已有人员，如果该字段为0， 就创建人员
		// 人员信息信息
		Name     string `json:"name"`
		Nick     string `json:"nick"`
		Birthday string `json:"birthday"`
		Phone    string `json:"phone"`
		Priority int    `json:"priority"` //添加丈夫的时候不允许编辑排行
	}
	var input InputInfo
	err := json.Unmarshal([]byte(jsonData), &input)
	if err != nil {
		return FailRet(CodeParamError, err)
	}
	target_person := input.TargetPerson

	//校验当前人
	isContains, err := api_family_contain_person(tx, input.Family, []int64{person_id, target_person})
	if err != nil {
		return DBErrReturn("校验当前人异常", err)
	}
	if !isContains {
		return ParamErrReturn("校验当前人失败")
	}

	//校验妻子
	var couple_id int64
	var husband int64
	var priority int
	err = tx.QueryRow("select id, ifnull(husband, 0) as husband, priority from tb_couple where family = ? and wife = ?", input.Family, input.TargetPerson).Scan(&couple_id, &husband, &priority)
	if err != nil {
		if err.Error() == sql.ErrNoRows.Error() {
			return SvrErrReturn("选取人不是本家族的女性, 添加丈夫失败")
		} else {
			return DBErrReturn("校验妻子异常", err)
		}
	}
	if husband != 0 {
		return SvrErrReturn("选取人已经有丈夫，不能再添加")
	}
	if priority != input.Priority {
		return SvrErrReturn("丈夫的排行和妻子对应不上，请重新添加")
	}

	//添加人员
	var newPersonId int64
	if input.SelectPerson == 0 {
		//添加新人员
		result, err := tx.Exec("insert into tb_person(name, sex, birthday, phone) values (?, 1, ?, ?)", input.Name, input.Birthday, input.Phone)
		if err != nil {
			return DBErrReturn("新增人员失败", err)
		}
		newPersonId, err = result.LastInsertId()
		if err != nil {
			return DBErrReturn("新增人员返回错误", err)
		}
		//添加人员昵称
		if len(input.Nick) > 0 {
			_, err = tx.Exec("insert into tb_nicks(family, main_person, call_person, nick) values (?, ?, ?, ?)", input.Family, person_id, newPersonId, input.Nick)
			if err != nil {
				return DBErrReturn("保存人员昵称失败", err)
			}
		}
	} else {
		//添加别的家族的已有人员

		//校验性别
		var id int64
		var sex int
		err = tx.QueryRow("select id, sex from tb_person where id = ?", input.SelectPerson).Scan(&id, &sex)
		if err != nil || id == 0 {
			return DBErrReturn("校验选取人失败", err)
		}
		if sex != 1 {
			return SvrErrReturn("选取人性别错误！")
		}
		//校验选取人不在当前家族
		isContains, err := api_family_contain_person(tx, input.Family, []int64{input.SelectPerson})
		if err != nil {
			return DBErrReturn("校验选取人是否在当前家族异常", err)
		}
		if isContains {
			return SvrErrReturn("选取人在当前家族已经存在，不能添加")
		}
		//校验当前登录用户和选取人同属于某一个家族
		in_one_family, err := api_two_person_in_one_family(tx, person_id, input.SelectPerson)
		if err != nil {
			return FailRet(CodeDatabaseError, err)
		}
		if !in_one_family {
			return SvrErrReturn("选取人错误，选取人和当前登录人不共同属于任一家族")
		}

		//更新人员信息
		_, err = tx.Exec("update tb_person set name = ?, birthday = ?, phone = ? where id = ?", input.Name, input.Birthday, input.Phone, input.SelectPerson)
		if err != nil {
			return DBErrReturn("更新人员信息失败", err)
		}
		//添加人员昵称
		if len(input.Nick) > 0 {
			_, err = tx.Exec("insert into tb_nicks(family, main_person, call_person, nick) values (?, ?, ?, ?)", input.Family, person_id, input.SelectPerson, input.Nick)
			if err != nil {
				return DBErrReturn("更新人员昵称失败", err)
			}
		}

		newPersonId = input.SelectPerson
	}

	//更新家族成员表
	_, err = tx.Exec("insert into tb_family_member(family_id, person_id, add_person_id) values (?, ?, ?)", input.Family, newPersonId, person_id)
	if err != nil {
		return DBErrReturn("新增家族成员失败", err)
	}

	//更新couple对象
	result, err := tx.Exec("update tb_couple set husband = ? where id = ?", newPersonId, couple_id)
	if err != nil {
		return DBErrReturn("更新couple对象失败", err)
	}
	count, _ := result.RowsAffected()
	if 0 == count {
		return SvrErrReturn("更新couple对象失败")
	}

	ret, err := api_get_family_info(tx, person_id, input.Family)
	if err != nil {
		return FailRet(CodeDatabaseError, err)
	}
	return SuccRet(ret)
}

//添加妻子
func family_add_wife(tx *sql.Tx, person_id int64, jsonData string) *ReturnStruct {
	type InputInfo struct {
		Family       int64 `json:"family"`
		TargetPerson int64 `json:"target_person"` //要添加妻子的人

		SelectPerson int64 `json:"select_person"` //新增已有人员，如果该字段为0， 就创建人员
		// 人员信息信息
		Name     string `json:"name"`
		Nick     string `json:"nick"`
		Birthday string `json:"birthday"`
		Phone    string `json:"phone"`
		Priority int    `json:"priority"` //添加妻子的时候不允许编辑排行
	}
	var input InputInfo
	err := json.Unmarshal([]byte(jsonData), &input)
	if err != nil {
		return FailRet(CodeParamError, err)
	}
	target_person := input.TargetPerson

	//校验当前人
	isContains, err := api_family_contain_person(tx, input.Family, []int64{person_id, target_person})
	if err != nil {
		return DBErrReturn("校验当前人异常", err)
	}
	if !isContains {
		return ParamErrReturn("校验当前人失败")
	}

	//校验丈夫
	var couple_id int64
	var wife int64
	var priority int
	err = tx.QueryRow("select id, ifnull(wife, 0) as wife, priority from tb_couple where family = ? and husband = ?", input.Family, input.TargetPerson).Scan(&couple_id, &wife, &priority)
	if err != nil {
		if err.Error() == sql.ErrNoRows.Error() {
			return SvrErrReturn("选取人不是本家族的男性, 添加妻子失败")
		} else {
			return DBErrReturn("校验丈夫异常", err)
		}
	}
	if wife != 0 {
		return SvrErrReturn("选取人已经有妻子，不能再添加")
	}
	if priority != input.Priority {
		return SvrErrReturn("妻子的排行和丈夫对应不上，请重新添加")
	}

	//添加人员
	var newPersonId int64
	if input.SelectPerson == 0 {
		//添加新人员
		result, err := tx.Exec("insert into tb_person(name, sex, birthday, phone) values (?, 0, ?, ?)", input.Name, input.Birthday, input.Phone)
		if err != nil {
			return DBErrReturn("新增人员失败", err)
		}
		newPersonId, err = result.LastInsertId()
		if err != nil {
			return DBErrReturn("新增人员返回错误", err)
		}
		//添加人员昵称
		if len(input.Nick) > 0 {
			_, err = tx.Exec("insert into tb_nicks(family, main_person, call_person, nick) values (?, ?, ?, ?)", input.Family, person_id, newPersonId, input.Nick)
			if err != nil {
				return DBErrReturn("保存人员昵称失败", err)
			}
		}
	} else {
		//添加别的家族的已有人员

		//校验性别
		var id int64
		var sex int
		err = tx.QueryRow("select id, sex from tb_person where id = ?", input.SelectPerson).Scan(&id, &sex)
		if err != nil || id == 0 {
			return DBErrReturn("校验选取人失败", err)
		}
		if sex != 0 {
			return SvrErrReturn("选取人性别错误！")
		}
		//校验选取人不在当前家族
		isContains, err := api_family_contain_person(tx, input.Family, []int64{input.SelectPerson})
		if err != nil {
			return DBErrReturn("校验选取人是否在当前家族异常", err)
		}
		if isContains {
			return SvrErrReturn("选取人在当前家族已经存在，不能添加")
		}
		//校验当前登录用户和选取人同属于某一个家族
		in_one_family, err := api_two_person_in_one_family(tx, person_id, input.SelectPerson)
		if err != nil {
			return FailRet(CodeDatabaseError, err)
		}
		if !in_one_family {
			return SvrErrReturn("选取人错误，选取人和当前登录人不共同属于任一家族")
		}

		//更新人员信息
		_, err = tx.Exec("update tb_person set name = ?, birthday = ?, phone = ? where id = ?", input.Name, input.Birthday, input.Phone, input.SelectPerson)
		if err != nil {
			return DBErrReturn("更新人员信息失败", err)
		}
		//添加人员昵称
		if len(input.Nick) > 0 {
			_, err = tx.Exec("insert into tb_nicks(family, main_person, call_person, nick) values (?, ?, ?, ?)", input.Family, person_id, input.SelectPerson, input.Nick)
			if err != nil {
				return DBErrReturn("更新人员昵称失败", err)
			}
		}

		newPersonId = input.SelectPerson
	}

	//更新家族成员表
	_, err = tx.Exec("insert into tb_family_member(family_id, person_id, add_person_id) values (?, ?, ?)", input.Family, newPersonId, person_id)
	if err != nil {
		return DBErrReturn("新增家族成员失败", err)
	}
	//更新couple对象
	result, err := tx.Exec("update tb_couple set wife = ? where id = ?", newPersonId, couple_id)
	if err != nil {
		return DBErrReturn("更新couple对象失败", err)
	}
	count, _ := result.RowsAffected()
	if 0 == count {
		return SvrErrReturn("更新couple对象失败")
	}

	ret, err := api_get_family_info(tx, person_id, input.Family)
	if err != nil {
		return FailRet(CodeDatabaseError, err)
	}
	return SuccRet(ret)
}

//添加兄弟姊妹
func family_add_brother(tx *sql.Tx, person_id int64, jsonData string) *ReturnStruct {
	type InputInfo struct {
		Family       int64 `json:"family"`
		TargetPerson int64 `json:"target_person"` //要添加兄弟的人

		SelectPerson int64 `json:"select_person"` //新增已有人员，如果该字段为0， 就创建人员
		// 人员信息信息
		Name     string `json:"name"`
		Sex      int    `json:"sex"` //性别  1表示男， 0表示女  , 仅仅新增人员的时候有效
		Nick     string `json:"nick"`
		Birthday string `json:"birthday"`
		Phone    string `json:"phone"`
		Priority int    `json:"priority"`
	}
	var input InputInfo
	err := json.Unmarshal([]byte(jsonData), &input)
	if err != nil {
		return FailRet(CodeParamError, err)
	}
	target_person := input.TargetPerson
	if input.Sex != 0 && input.Sex != 1 {
		return ParamErrReturn("性别参数错误")
	}
	if input.Priority < 1 || input.Priority > 20 {
		return ParamErrReturn("排行参数超出范围!")
	}

	//校验当前人
	isContains, err := api_family_contain_person(tx, input.Family, []int64{person_id, target_person})
	if err != nil {
		return DBErrReturn("校验当前人异常", err)
	}
	if !isContains {
		return ParamErrReturn("校验当前人失败")
	}

	//查找当前couple和父couple
	var couple_id int64
	var target_priority int
	var parent_couple_id int64
	err = tx.QueryRow("select a.id as coupleId, a.priority, ifnull(b.parent, 0) as parentCoupleId from tb_couple a left join tb_parents b on a.family = b.family and a.id = b.child where a.family = ? and (a.husband = ? or a.wife = ?)", input.Family, target_person, target_person).Scan(&couple_id, &target_priority, &parent_couple_id)
	if err != nil {
		if err.Error() == sql.ErrNoRows.Error() {
			return SvrErrReturn("查找操作人couple异常")
		} else {
			return DBErrReturn("查询父couple异常", err)
		}
	}

	//校验排行
	if parent_couple_id != 0 {
		priorities, err := api_get_child_can_select_priorities(tx, input.Family, parent_couple_id)
		if err != nil {
			return FailRet(CodeDatabaseError, err)
		}
		if len(priorities) == 0 {
			return SvrErrReturn("兄弟姊妹最多支持20个，已满，不能继续添加")
		}
		if !ArrContainInt(priorities, input.Priority) {
			return ParamErrReturn("排行参数无效")
		}
	} else {
		//只有target一个couple, 不存在别的兄弟姊妹
		if input.Priority == target_priority {
			return SvrErrReturn("选择的排行和操作人的排行冲突！")
		}
	}

	//添加人员
	var newPersonId int64
	if input.SelectPerson == 0 {
		//添加新人员
		result, err := tx.Exec("insert into tb_person(name, sex, birthday, phone) values (?, ?, ?, ?)", input.Name, input.Sex, input.Birthday, input.Phone)
		if err != nil {
			return DBErrReturn("新增人员失败", err)
		}
		newPersonId, err = result.LastInsertId()
		if err != nil {
			return DBErrReturn("新增人员返回错误", err)
		}
		//添加人员昵称
		if len(input.Nick) > 0 {
			_, err = tx.Exec("insert into tb_nicks(family, main_person, call_person, nick) values (?, ?, ?, ?)", input.Family, person_id, newPersonId, input.Nick)
			if err != nil {
				return DBErrReturn("保存人员昵称失败", err)
			}
		}
	} else {
		//添加别的家族的已有人员

		//校验选取人不在当前家族
		isContains, err := api_family_contain_person(tx, input.Family, []int64{input.SelectPerson})
		if err != nil {
			return DBErrReturn("校验选取人是否在当前家族异常", err)
		}
		if isContains {
			return SvrErrReturn("选取人在当前家族已经存在，不能添加")
		}
		//校验当前登录用户和选取人同属于某一个家族
		in_one_family, err := api_two_person_in_one_family(tx, person_id, input.SelectPerson)
		if err != nil {
			return FailRet(CodeDatabaseError, err)
		}
		if !in_one_family {
			return SvrErrReturn("选取人错误，选取人和当前登录人不共同属于任一家族")
		}
		//查找选取人性别
		err = tx.QueryRow("select sex from tb_person where id = ?", input.SelectPerson).Scan(&input.Sex)
		if err != nil {
			return DBErrReturn("查找选取人性别失败", err)
		}

		//更新人员信息
		_, err = tx.Exec("update tb_person set name = ?, birthday = ?, phone = ? where id = ?", input.Name, input.Birthday, input.Phone, input.SelectPerson)
		if err != nil {
			return DBErrReturn("更新人员信息失败", err)
		}
		//添加人员昵称
		if len(input.Nick) > 0 {
			_, err = tx.Exec("insert into tb_nicks(family, main_person, call_person, nick) values (?, ?, ?, ?)", input.Family, person_id, input.SelectPerson, input.Nick)
			if err != nil {
				return DBErrReturn("更新人员昵称失败", err)
			}
		}

		newPersonId = input.SelectPerson
	}

	//更新家族成员表
	_, err = tx.Exec("insert into tb_family_member(family_id, person_id, add_person_id) values (?, ?, ?)", input.Family, newPersonId, person_id)
	if err != nil {
		return DBErrReturn("新增家族成员失败", err)
	}

	//新增子couple对象
	var newCoupleId int64
	if input.Sex == 1 {
		//男
		result, err := tx.Exec("insert into tb_couple(family, husband, priority) values (?, ?, ?)", input.Family, newPersonId, input.Priority)
		if err != nil {
			return DBErrReturn("新增子couple失败", err)
		}
		newCoupleId, err = result.LastInsertId()
		if err != nil {
			return DBErrReturn("新增子couple返回错误", err)
		}
	} else {
		//女
		result, err := tx.Exec("insert into tb_couple(family, wife, priority) values (?, ?, ?)", input.Family, newPersonId, input.Priority)
		if err != nil {
			return DBErrReturn("新增子couple失败", err)
		}
		newCoupleId, err = result.LastInsertId()
		if err != nil {
			return DBErrReturn("新增子couple返回错误", err)
		}
	}

	//新增父子表
	_, err = tx.Exec("insert into tb_parents(family, child, child_male, parent) values (?, ?, ?, ?)", input.Family, newCoupleId, input.Sex, parent_couple_id)
	if err != nil {
		return DBErrReturn("新增父子表失败", err)
	}

	//返回家族信息
	ret, err := api_get_family_info(tx, person_id, input.Family)
	if err != nil {
		return FailRet(CodeDatabaseError, err)
	}
	return SuccRet(ret)
}

//添加子女
func family_add_child(tx *sql.Tx, person_id int64, jsonData string) *ReturnStruct {
	type InputInfo struct {
		Family       int64 `json:"family"`
		TargetPerson int64 `json:"target_person"` //要添加子女的人

		SelectPerson int64 `json:"select_person"` //新增已有人员，如果该字段为0， 就创建人员
		// 人员信息信息
		Name     string `json:"name"`
		Sex      int    `json:"sex"` //性别  1表示男， 0表示女  , 仅仅新增人员的时候有效
		Nick     string `json:"nick"`
		Birthday string `json:"birthday"`
		Phone    string `json:"phone"`
		Priority int    `json:"priority"`
	}
	var input InputInfo
	err := json.Unmarshal([]byte(jsonData), &input)
	if err != nil {
		return FailRet(CodeParamError, err)
	}
	target_person := input.TargetPerson
	if input.Sex != 0 && input.Sex != 1 {
		return ParamErrReturn("性别参数错误")
	}
	if input.Priority < 1 || input.Priority > 20 {
		return ParamErrReturn("排行参数超出范围!")
	}

	//校验当前人
	isContains, err := api_family_contain_person(tx, input.Family, []int64{person_id, target_person})
	if err != nil {
		return DBErrReturn("校验当前人异常", err)
	}
	if !isContains {
		return ParamErrReturn("校验当前人失败")
	}

	//查找父couple
	var couple_id int64
	err = tx.QueryRow("select id from tb_couple where family = ? and (husband = ? or wife = ?)", input.Family, input.TargetPerson, input.TargetPerson).Scan(&couple_id)
	if err != nil {
		if err.Error() == sql.ErrNoRows.Error() {
			return SvrErrReturn("查找操作人couple异常")
		} else {
			return DBErrReturn("查询父couple异常", err)
		}
	}

	//校验排行
	priorities, err := api_get_child_can_select_priorities(tx, input.Family, couple_id)
	if err != nil {
		return FailRet(CodeDatabaseError, err)
	}
	if len(priorities) == 0 {
		return SvrErrReturn("子女最多支持20个，已满，不能继续添加子女")
	}
	if !ArrContainInt(priorities, input.Priority) {
		return ParamErrReturn("排行参数无效")
	}

	//添加人员
	var newPersonId int64
	if input.SelectPerson == 0 {
		//添加新人员
		result, err := tx.Exec("insert into tb_person(name, sex, birthday, phone) values (?, ?, ?, ?)", input.Name, input.Sex, input.Birthday, input.Phone)
		if err != nil {
			return DBErrReturn("新增人员失败", err)
		}
		newPersonId, err = result.LastInsertId()
		if err != nil {
			return DBErrReturn("新增人员返回错误", err)
		}
		//添加人员昵称
		if len(input.Nick) > 0 {
			_, err = tx.Exec("insert into tb_nicks(family, main_person, call_person, nick) values (?, ?, ?, ?)", input.Family, person_id, newPersonId, input.Nick)
			if err != nil {
				return DBErrReturn("保存人员昵称失败", err)
			}
		}
	} else {
		//添加别的家族的已有人员

		//校验选取人不在当前家族
		isContains, err := api_family_contain_person(tx, input.Family, []int64{input.SelectPerson})
		if err != nil {
			return DBErrReturn("校验选取人是否在当前家族异常", err)
		}
		if isContains {
			return SvrErrReturn("选取人在当前家族已经存在，不能添加")
		}
		//校验当前登录用户和选取人同属于某一个家族
		in_one_family, err := api_two_person_in_one_family(tx, person_id, input.SelectPerson)
		if err != nil {
			return FailRet(CodeDatabaseError, err)
		}
		if !in_one_family {
			return SvrErrReturn("选取人错误，选取人和当前登录人不共同属于任一家族")
		}
		//查找选取人性别
		err = tx.QueryRow("select sex from tb_person where id = ?", input.SelectPerson).Scan(&input.Sex)
		if err != nil {
			return DBErrReturn("查找选取人性别失败", err)
		}

		//更新人员信息
		_, err = tx.Exec("update tb_person set name = ?, birthday = ?, phone = ? where id = ?", input.Name, input.Birthday, input.Phone, input.SelectPerson)
		if err != nil {
			return DBErrReturn("更新人员信息失败", err)
		}
		//添加人员昵称
		if len(input.Nick) > 0 {
			_, err = tx.Exec("insert into tb_nicks(family, main_person, call_person, nick) values (?, ?, ?, ?)", input.Family, person_id, input.SelectPerson, input.Nick)
			if err != nil {
				return DBErrReturn("更新人员昵称失败", err)
			}
		}

		newPersonId = input.SelectPerson
	}

	//更新家族成员表
	_, err = tx.Exec("insert into tb_family_member(family_id, person_id, add_person_id) values (?, ?, ?)", input.Family, newPersonId, person_id)
	if err != nil {
		return DBErrReturn("新增家族成员失败", err)
	}

	//新增子couple对象
	var newCoupleId int64
	if input.Sex == 1 {
		//男
		result, err := tx.Exec("insert into tb_couple(family, husband, priority) values (?, ?, ?)", input.Family, newPersonId, input.Priority)
		if err != nil {
			return DBErrReturn("新增子couple失败", err)
		}
		newCoupleId, err = result.LastInsertId()
		if err != nil {
			return DBErrReturn("新增子couple返回错误", err)
		}
	} else {
		//女
		result, err := tx.Exec("insert into tb_couple(family, wife, priority) values (?, ?, ?)", input.Family, newPersonId, input.Priority)
		if err != nil {
			return DBErrReturn("新增子couple失败", err)
		}
		newCoupleId, err = result.LastInsertId()
		if err != nil {
			return DBErrReturn("新增子couple返回错误", err)
		}
	}

	//新增父子表
	_, err = tx.Exec("insert into tb_parents(family, child, child_male, parent) values (?, ?, ?, ?)", input.Family, newCoupleId, input.Sex, couple_id)
	if err != nil {
		return DBErrReturn("新增父子表失败", err)
	}

	//返回家族信息
	ret, err := api_get_family_info(tx, person_id, input.Family)
	if err != nil {
		return FailRet(CodeDatabaseError, err)
	}
	return SuccRet(ret)
}

//从家族中移除人员
func family_delete_person(tx *sql.Tx, person_id int64, jsonData string) *ReturnStruct {
	type InputInfo struct {
		Family       int64 `json:"family"`
		TargetPerson int64 `json:"target_person"` //要移除的人
	}
	var input InputInfo
	err := json.Unmarshal([]byte(jsonData), &input)
	if err != nil {
		return FailRet(CodeParamError, err)
	}
	target_person := input.TargetPerson

	//校验当前人
	isContains, err := api_family_contain_person(tx, input.Family, []int64{person_id, target_person})
	if err != nil {
		return DBErrReturn("校验当前人异常", err)
	}
	if !isContains {
		return ParamErrReturn("校验当前人失败")
	}

	//判断能不能移除
	var wife int64
	var husband int64
	var coupleId int64
	var parentKey int64 //父子表主键
	var child_male int
	var parent int64
	tx.QueryRow(`
	select ifnull(wife, 0) as wife, ifnull(husband, 0) as husband, a.id, b.id, ifnull(b.child_male, 1) as child_male, ifnull(b.parent, 0) as parent 
	from tb_couple a left join tb_parents b on a.family = b.family and a.id = b.child 
	where a.family = ? and (a.wife = ? or a.husband = ?)`, input.Family, target_person, target_person).
		Scan(&wife, &husband, &coupleId, &parentKey, &child_male, &parent)
	if err != nil {
		return DBErrReturn("当前人couple校验", err)
	}
	if coupleId == 0 {
		return DBErrReturn("当前人couple查找失败", err)
	}

	var another_half int64 //另一半
	if target_person == husband {
		another_half = wife
	} else {
		another_half = husband
	}

	has_own_parent := false //是否存在自己的长辈或兄弟姊妹
	if parent != 0 {
		if child_male == 1 {
			if target_person == husband {
				has_own_parent = true
			}
		} else {
			if target_person == wife {
				has_own_parent = true
			}
		}
	}

	if has_own_parent {
		if another_half != 0 {
			return SvrErrReturn("夫妻双方存在长辈或兄弟姊妹的一方后删除")
		} else {
			child_num := 0 //当前选中人子女的数目
			err = tx.QueryRow("select count(*) from tb_parents where family = ? and parent = ?", input.Family, coupleId).Scan(&child_num)
			if err != nil {
				return DBErrReturn("查找子女数量", err)
			}
			if child_num > 0 {
				return SvrErrReturn("又有长辈又有子女不能直接删除")
			}
		}
	}

	//判断是否同时删除成员和个人资料
	other_family_num := 0 //所属的其他家族个数
	err = tx.QueryRow("select count(*) from tb_family_member where person_id = ? and family_id != ?", target_person, input.Family).Scan(&other_family_num)
	if err != nil {
		return DBErrReturn("查找其他家族", err)
	}
	is_delete_person := other_family_num == 0
	if is_delete_person {
		//只存在于目前一个家族，需要同时移除成员和个人资料
		//搜索有没有文章或者图片
		article_num := 0
		err = tx.QueryRow("select count(*) from tb_person_article where person_id = ?", target_person).Scan(&article_num)
		if err != nil {
			return DBErrReturn("查找文章个数", err)
		}
		if article_num > 0 {
			return SvrErrReturn("请先清空被移除人的个人记事")
		}

		image_num := 0
		err = tx.QueryRow("select count(*) from tb_person_pic where person_id = ?", target_person).Scan(&image_num)
		if err != nil {
			return DBErrReturn("查找图片个数", err)
		}
		if image_num > 0 {
			return SvrErrReturn("请先清空被移除人的个人图片")
		}

		//先转移权限, 从被删除人转给删除人
		err := api_transfer_power(tx, input.Family, target_person, person_id)
		if err != nil {
			return SvrErrReturn(err.Error())
		}
	}

	//先从家族中剔除
	_, err = tx.Exec("delete from tb_family_member where family_id = ? and person_id = ?", input.Family, target_person)
	if err != nil {
		return DBErrReturn("移除成员", err)
	}
	_, err = tx.Exec("delete from tb_nicks where family = ? and main_person = ? and call_person = ?", input.Family, person_id, target_person)
	if err != nil {
		return DBErrReturn("删除人员在家族中的昵称失败", err)
	}
	//处理夫妻表和父子表
	if another_half != 0 {
		//自己一定没有长辈，couple对象不变，仅仅删除自己
		if target_person == wife {
			_, err = tx.Exec("update tb_couple set wife = NULL where id = ?", coupleId)
			if err != nil {
				return DBErrReturn("重置当前人couple对象", err)
			}
		} else {
			_, err = tx.Exec("update tb_couple set husband = NULL where id = ?", coupleId)
			if err != nil {
				return DBErrReturn("重置当前人couple对象", err)
			}
		}
	} else {
		//可能需要删除当前couple, 删除当前couple以前，先看看有没有tb_parents的引用。
		if has_own_parent {
			//一定没有子女
			if parentKey != 0 {
				_, err = tx.Exec("delete from tb_parents where id = ?", parentKey)
				if err != nil {
					return DBErrReturn("删除父子表", err)
				}

				var mother int64
				var father int64
				err = tx.QueryRow("select ifnull(wife, 0), ifnull(husband, 0) from tb_couple where id = ?", parent).Scan(&mother, &father)
				if err != nil {
					return DBErrReturn("查找父母亲", err)
				}
				if mother == 0 && father == 0 {
					//父母都是空的，只有兄弟姊妹。如果只剩下一个兄弟姊妹，将该兄的父子表也删除
					var brother_num int64
					err = tx.QueryRow("select count(*) from tb_parents where family = ? and parent = ?", input.Family, parent).Scan(&brother_num)
					if err != nil {
						return DBErrReturn("查找兄弟姊妹数目", err)
					}
					if brother_num == 1 {
						//最后一个
						_, err = tx.Exec("delete from tb_parents where family = ? and parent = ?", input.Family, parent)
						if err != nil {
							return DBErrReturn("删除单个兄弟", err)
						}
					}
					if brother_num <= 1 && parent != 0 {
						//删除parent couple
						_, err = tx.Exec("delete tb_couple where id = ?", parent)
						if err != nil {
							return DBErrReturn("删除空长辈", err)
						}
					}
				}
			}

			_, err = tx.Exec("delete from tb_couple where id = ?", coupleId)
			if err != nil {
				return DBErrReturn("删除夫妻表", err)
			}

		} else {
			//没有另一半，没有长辈和兄弟姊妹
			//子女多于一个的情况下保留空couple，该空couple用来表示兄弟姊妹关系。
			if parentKey != 0 {
				_, err = tx.Exec("delete from tb_parents where id = ?", parentKey)
				if err != nil {
					return DBErrReturn("删除父子表", err)
				}
			}

			child_num := 0 //当前选中人子女的数目
			err = tx.QueryRow("select count(*) from tb_parents where family = ? and parent = ?", input.Family, coupleId).Scan(&child_num)
			if err != nil {
				return DBErrReturn("查找子女数量", err)
			}
			if child_num <= 1 {
				if child_num > 0 {
					_, err = tx.Exec("delete from tb_parents where family = ? and parent = ?", input.Family, coupleId)
					if err != nil {
						return DBErrReturn("删除父子表", err)
					}
				}
				_, err = tx.Exec("delete from tb_couple where id = ?", coupleId)
				if err != nil {
					return DBErrReturn("删除夫妻表", err)
				}
			} else {
				//多个子女保留空couple
				_, err = tx.Exec("update tb_couple set wife = NULL, husband = NULL where id = ?", coupleId)
				if err != nil {
					return DBErrReturn("保留空couple", err)
				}
			}
		}
	}

	if is_delete_person {
		//实际删除人的函数

		//删除成员, 注意需要删删除关联表，不然会删除失败
		_, err = tx.Exec("delete from tb_person_attr where person_id = ?", target_person)
		if err != nil {
			return DBErrReturn("删除人员属性", err)
		}
		_, err = tx.Exec("delete from tb_nicks where main_person = ? or call_person = ?", target_person, target_person)
		if err != nil {
			return DBErrReturn("删除人员昵称", err)
		}
		_, err = tx.Exec("delete from tb_session where person_id = ?", target_person)
		if err != nil {
			return DBErrReturn("删除人员session", err)
		}

		_, err = tx.Exec("delete from tb_person where id = ?", target_person)
		if err != nil {
			return DBErrReturn("删除人员失败", err)
		}
	}

	ret, err := api_get_family_info(tx, person_id, input.Family)
	if err != nil {
		return FailRet(CodeDatabaseError, err)
	}
	return SuccRet(ret)
}

//在一个家族范围内将某个人的权限转移给另一个人，转移后转移人的权限将消失
//只有同一个家族的人员之间可以权限转移
func api_transfer_power(tx *sql.Tx, family int64, origin_person int64, target_person int64) error {
	//校验当前人
	isContains, err := api_family_contain_person(tx, family, []int64{origin_person, target_person})
	if err != nil {
		return PrefixError("转移权限-校验异常", err)
	}
	if !isContains {
		return errors.New("转移权限-校验失败")
	}

	_, err = tx.Exec("update tb_family set create_person = ? where id = ? and create_person = ?", target_person, family, origin_person)
	if err != nil {
		return PrefixError("更新家族创建人", err)
	}

	_, err = tx.Exec("update tb_family_member set add_person_id = ? where family_id = ? and add_person_id = ?", target_person, family, origin_person)
	if err != nil {
		return PrefixError("更新人员添加者", err)
	}

	_, err = tx.Exec("update tb_person_article a, tb_family_member b set a.create_person = ? where a.person_id = b.person_id and b.family_id = ? and a.create_person = ?", target_person, family, origin_person)
	if err != nil {
		return PrefixError("更新文章创建人", err)
	}

	return nil
}

//获取关系编辑页初始信息, 家族中已有该人
//该页和个人信息页的区别是： 个人信息页主要存储个人信息相关（不能编辑性别和排行），此页主要存储关系编辑相关。
func get_relation_person_info(tx *sql.Tx, person_id int64, jsonData string) *ReturnStruct {
	type InputInfo struct {
		Family       int64 `json:"family"`
		TargetPerson int64 `json:"target_person"` //家族中的人
	}
	var input InputInfo
	err := json.Unmarshal([]byte(jsonData), &input)
	if err != nil {
		return FailRet(CodeParamError, err)
	}
	target_person := input.TargetPerson

	//校验当前人
	isContains, err := api_family_contain_person(tx, input.Family, []int64{person_id, target_person})
	if err != nil {
		return DBErrReturn("校验当前人异常", err)
	}
	if !isContains {
		return SvrErrReturn("当前人不在家族中")
	}

	//声明接口返回数据
	type Result struct {
		Info                map[string]interface{} `json:"info"`                  //个人信息
		CanSelectPriorities []int                  `json:"can_select_priorities"` //可选择的兄弟排行
	}
	var result Result

	//获取关系信息
	rows, err := tx.Query(`
		select a.name, a.sex, a.birthday, a.phone, ifnull(b.nick, '') as nick, c.priority, c.id as couple_id  
		from tb_person a 
		left join tb_nicks b on b.family = ? and b.main_person = ? and b.call_person = a.id
		join tb_couple c on c.family = ? and (c.wife = a.id or c.husband = a.id)
		where a.id = ?`, input.Family, person_id, input.Family, target_person)
	if err != nil {
		return DBErrReturn("查询关系信息", err)
	}
	data, _ := SelectResultFromRows(rows)
	if data == nil || len(data) == 0 {
		return SvrErrReturn("查询关系-查询人员异常")
	}
	result.Info = data[0]

	coupleId, _ := result.Info["couple_id"].(int64)
	result.CanSelectPriorities, err = api_get_can_select_priorities(tx, coupleId)
	if err != nil {
		return FailRet(CodeDatabaseError, err)
	}
	priority, _ := result.Info["priority"].(int64)
	priority_index := -1
	for i := 0; i < len(result.CanSelectPriorities); i++ {
		if int(priority) == result.CanSelectPriorities[i] {
			priority_index = i
			break
		}
	}
	if -1 == priority_index {
		return SvrErrReturn("查询排序异常")
	}
	result.Info["priority_index"] = priority_index
	return SuccRet(result)
}

//获取关系编辑页初始信息, 选择后待添加进家族中
//该页和个人信息页的区别是： 个人信息页主要存储个人信息相关（不能编辑性别和排行），此页主要存储关系编辑相关。
func get_relation_person_info_add(tx *sql.Tx, person_id int64, jsonData string) *ReturnStruct {
	type InputInfo struct {
		SelectFamily   int64 `json:"select_family"` //选择的家族
		Family         int64 `json:"family"`        //待添加进的家族
		TargetPerson   int64 `json:"select_person"` //选择后待添加进家族中的人
		ParentCoupleId int64 `json:"parent_couple"` //待添加进的家族中的父couple id, 用来预估可选兄弟排行
	}
	var input InputInfo
	err := json.Unmarshal([]byte(jsonData), &input)
	if err != nil {
		return FailRet(CodeParamError, err)
	}
	target_person := input.TargetPerson

	//校验选择家族
	isContains, err := api_family_contain_person(tx, input.SelectFamily, []int64{person_id, target_person})
	if err != nil {
		return DBErrReturn("校验选择家族异常", err)
	}
	if !isContains {
		return SvrErrReturn("操作失败-选择的家族中不包含选择人")
	}

	//校验当前家族
	isContains, err = api_family_contain_person(tx, input.Family, []int64{target_person})
	if err != nil {
		return DBErrReturn("校验当前人异常", err)
	}
	if isContains {
		return SvrErrReturn("添加选择人-家族中已有此人，不能添加")
	}

	//校验父coupleid
	if input.ParentCoupleId != 0 {
		var count int64
		tx.QueryRow("select count(*) from tb_couple where id = ? and family = ?", input.ParentCoupleId, input.Family).Scan(&count)
		if count == 0 {
			return ParamErrReturn("父couple参数异常")
		}
	}

	//声明接口返回数据
	type Result struct {
		Info                map[string]interface{} `json:"info"`                  //个人信息
		CanSelectPriorities []int                  `json:"can_select_priorities"` //可选择的兄弟排行
	}
	var result Result

	//获取关系信息
	rows, err := tx.Query(`
		select a.name, a.sex, a.birthday, a.phone, ifnull(b.nick, '') as nick
		from tb_person a 
		left join tb_nicks b on b.family = ? and b.main_person = ? and b.call_person = a.id 
		where a.id = ?`, input.SelectFamily, person_id, target_person)
	if err != nil {
		return DBErrReturn("新增人员-查询信息", err)
	}
	data, _ := SelectResultFromRows(rows)
	if data == nil || len(data) == 0 {
		return SvrErrReturn("新增人员-查询人员异常")
	}
	result.Info = data[0]

	//根据父coupleid获取可选的排行
	if input.ParentCoupleId == 0 {
		arr := make([]int, 0)
		for i := 1; i <= 20; i++ {
			arr = append(arr, i)
		}
		result.CanSelectPriorities = arr
	} else {
		//存在长辈，查询其他兄弟姊妹的排行
		rows, err := tx.Query("select a.id as coupleId, a.priority from tb_couple a join tb_parents b on a.family = b.family and a.id = b.child where b.family = ? and b.parent = ?", input.Family, input.ParentCoupleId)
		if err != nil {
			return DBErrReturn("查询兄弟姊妹排行异常", err)
		}
		data, _ := SelectResultFromRows(rows)
		brother_priorities, err := GetIntColumnFromResult(data, "priority") //兄弟姊妹已存在的排行
		if err != nil {
			return DBErrReturn("解析排行", err)
		}

		arr := make([]int, 0)
		for i := int64(1); i <= 20; i++ {
			if !ArrContainInt64(brother_priorities, i) {
				arr = append(arr, int(i))
			}
		}
		if len(arr) == 0 {
			return SvrErrReturn("最多支持20个兄弟姊妹，不能再添加了")
		}
		result.CanSelectPriorities = arr
	}

	return SuccRet(result)
}

//获取父母添加子女时可选择的兄弟姊妹排行
func get_child_can_select_priorities(tx *sql.Tx, person_id int64, jsonData string) *ReturnStruct {
	type InputInfo struct {
		Family         int64 `json:"family"`        //所在家族
		ParentCoupleId int64 `json:"parent_couple"` //父couple id, 用来预估可选兄弟排行
	}
	var input InputInfo
	err := json.Unmarshal([]byte(jsonData), &input)
	if err != nil {
		return FailRet(CodeParamError, err)
	}

	//校验家族
	isContains, err := api_family_contain_person(tx, input.Family, []int64{person_id})
	if err != nil {
		return DBErrReturn("校验家族异常", err)
	}
	if !isContains {
		return SvrErrReturn("操作失败-家族参数错误")
	}
	priorities, err := api_get_child_can_select_priorities(tx, input.Family, input.ParentCoupleId)
	if err != nil {
		return FailRet(CodeSvrERROR, err)
	}
	if len(priorities) == 0 {
		return SvrErrReturn("一个父母最多只能有20个子女，不能再添加了")
	}
	return SuccRet(priorities)
}

//获取添加兄弟姊妹时可选择的排行， 返回的可选排行中不包含当前待添加兄弟姊妹的人的排行
func get_brother_can_select_priorities(tx *sql.Tx, person_id int64, jsonData string) *ReturnStruct {
	type InputInfo struct {
		Family   int64 `json:"family"` //所在家族
		CoupleId int64 `json:"couple"` //当前待添加兄弟姊妹的couple id
	}
	var input InputInfo
	err := json.Unmarshal([]byte(jsonData), &input)
	if err != nil {
		return FailRet(CodeParamError, err)
	}

	//校验家族
	isContains, err := api_family_contain_person(tx, input.Family, []int64{person_id})
	if err != nil {
		return DBErrReturn("校验家族异常", err)
	}
	if !isContains {
		return SvrErrReturn("操作失败-家族参数错误")
	}

	//校验couple, 并查询当前couple的排行
	var priority int
	err = tx.QueryRow("select priority from tb_couple where family = ? and id = ?", input.Family, input.CoupleId).Scan(&priority)
	if err != nil {
		if err.Error() == sql.ErrNoRows.Error() {
			return ParamErrReturn("couple参数错误")
		} else {
			return DBErrReturn("校验couple异常", err)
		}
	}

	//返回可选择排行，但包含自己的排行
	priorities, err := api_get_can_select_priorities(tx, input.CoupleId)
	if err != nil {
		return FailRet(CodeSvrERROR, err)
	}
	priorities = ArrRemoveInt(priorities, priority) //删除当前的排行
	if len(priorities) == 0 {
		return SvrErrReturn("一个父母最多只能有20个子女，不能再添加了")
	}
	return SuccRet(priorities)
}

//编辑关系编辑页信息, 家族中已有该人
//该页和个人信息页的区别是： 个人信息页主要存储个人信息相关（不能编辑性别和排行），此页主要存储关系编辑相关。
func edit_relation_person_info(tx *sql.Tx, person_id int64, jsonData string) *ReturnStruct {
	type InputInfo struct {
		Family       int64 `json:"family"`
		TargetPerson int64 `json:"target_person"` //编辑人

		// 人员信息信息
		Name     string `json:"name"`
		Nick     string `json:"nick"`
		Birthday string `json:"birthday"`
		Phone    string `json:"phone"`
		Priority int    `json:"priority"`
	}
	var input InputInfo
	err := json.Unmarshal([]byte(jsonData), &input)
	if err != nil {
		return FailRet(CodeParamError, err)
	}
	target_person := input.TargetPerson
	if input.Priority < 1 || input.Priority > 20 {
		return ParamErrReturn("排行参数超出范围!")
	}

	//校验当前人
	isContains, err := api_family_contain_person(tx, input.Family, []int64{person_id, target_person})
	if err != nil {
		return DBErrReturn("校验当前人异常", err)
	}
	if !isContains {
		return ParamErrReturn("校验当前人失败")
	}

	//查找当前couple和父couple
	var couple_id int64
	var target_priority int
	var parent_couple_id int64
	err = tx.QueryRow("select a.id as coupleId, a.priority, ifnull(b.parent, 0) as parentCoupleId from tb_couple a left join tb_parents b on a.family = b.family and a.id = b.child where a.family = ? and (a.husband = ? or a.wife = ?)", input.Family, target_person, target_person).Scan(&couple_id, &target_priority, &parent_couple_id)
	if err != nil {
		if err.Error() == sql.ErrNoRows.Error() {
			return SvrErrReturn("查找操作人couple异常")
		} else {
			return DBErrReturn("查询父couple异常", err)
		}
	}

	//校验排行
	if parent_couple_id != 0 {
		if input.Priority != target_priority {
			priorities, err := api_get_child_can_select_priorities(tx, input.Family, parent_couple_id)
			if err != nil {
				return FailRet(CodeDatabaseError, err)
			}
			if !ArrContainInt(priorities, input.Priority) {
				return ParamErrReturn("排行参数无效")
			}
		}
	}

	//更新人员信息
	_, err = tx.Exec("update tb_person set name = ?, birthday = ?, phone = ? where id = ?", input.Name, input.Birthday, input.Phone, target_person)
	if err != nil {
		return DBErrReturn("更新人员信息失败", err)
	}
	//更新人员昵称
	_, err = tx.Exec("delete from tb_nicks where family = ? and main_person = ? and call_person = ?", input.Family, person_id, target_person)
	if err != nil {
		return DBErrReturn("更新旧昵称失败", err)
	}
	if len(input.Nick) > 0 {
		_, err = tx.Exec("insert into tb_nicks(family, main_person, call_person, nick) values (?, ?, ?, ?)", input.Family, person_id, target_person, input.Nick)
		if err != nil {
			return DBErrReturn("更新新昵称失败", err)
		}
	}

	//更新排行
	if input.Priority != target_priority {
		_, err = tx.Exec("update tb_couple set priority = ? where id = ?", input.Priority, couple_id)
		if err != nil {
			return DBErrReturn("更新排行失败", err)
		}
	}

	ret, err := api_get_family_info(tx, person_id, input.Family)
	if err != nil {
		return FailRet(CodeDatabaseError, err)
	}
	return SuccRet(ret)
}
